YUI JS Compressor Tool Extended

Goto download section now

I like to use YUI’s Compressor tool for minifying my javascripts. It’s brilliant. However my javascript API is becoming rather large and complex, and I wanted to use debugging facilities like printing log messages and littering my code with assertions as much as I need to, without worrying about removing them manually for the release version of the scripts. I didn’t find anything on the net that really supported what I wanted. So I wrote my own solution.

Presenting to you the “YUI Compressor extended” tool. It now has an extra option: --exclude-namespace namespaces. Where “namespaces” is a semi-colon separated list of global namespaces to be entirely removed from your javascript. That is, the declarations and usage of the global namespace.

What constitutes a “global namespace”?

Essentially, any global object. Here is a practical example to illustrate its intention where a global namespace called “debug” is declared:


/**
 * The debug namespace will be removed in release builds 
 */
debug = {};

debug.assert = function(cond, msg) {
    if (!cond) {
	throw new Error("Assertion failed" + (msg ? ": " + msg : ""));
    }
}

/**
 * Use this to run debug-version only code.
 * In the build, the code will be entirly removed since the debug namespace is excluded.
 */
debug.exec = function(func) {
    func();
}

debug.print = function(msg) {
   if (console && console.log) {
     console.log(msg);
   } else {
     // Here you might actually do something more realistic, like your own debug pane in a floating DIV.
     alert(msg);
   }
}

debug.println = function(msg) {
  debug.print(msg + "\n");
}

So debug is just a global object – intended to be a namespace. Now lets look at how your scripts might use it:

PrintDOMAction = function(startNode, startIndex, endNode, endIndex) {
	
	debug.assert(
		!(startNode.nodeName == "#text" && (startIndex >= startNode.nodeValue.length)),
		"Start index out of range"
	);
	
	debug.assert(
		!(endNode.nodeName == "#text" && (endIndex >= endNode.nodeValue.length)),
		"End index out of range"
	);
		
	debug.assert(
		!(startNode.nodeName == "#text" && startNode == endNode && startIndex > endIndex),
		"Invalid range"
	);

        // Set members
	this.startNodeRef = startNode;
	this.startingIndex = startIndex;
	this.endNodeRef = endNode;
	this.endingIndex = endIndex;
}

Here PrintDOMAction is a constructor function. This is an example of checking arguments with assertions.

Now when you use the extended YUI compressor with –exlude-namespace “debug” as an option, all the debug declarations will vanish and the PrintDOMAction constructor function will look like:

PrintDOMAction = function(startNode, startIndex, endNode, endIndex) {
	
        // Set members
	this.startNodeRef = startNode;
	this.startingIndex = startIndex;
	this.endNodeRef = endNode;
	this.endingIndex = endIndex;
}

(Assuming all whitespaces/newlines are preserved and munging is disabled so that it is not compressed).

Here’s a neat idea that may be helpful: to run could only in “debug mode” using the simple debug namespace presented above you would write:

...
debug.exec(function() {
  // You can have anything in this anonymous function and it will only be included in debug mode!
  var specialButton = document.createElement("input");
  specialButton.type = "button";
  specialButton.onclick = function() {
    alert("you clicked a special function, exclusively available to debug mode!");
  }
  document.body.appendChild(specialButton);
});
...

Usage

I have a bunch of perl/bash scripts that glue all my javascripts together (in the correct dependancy order), which then compresses the final large script using the YUI Compressor extended tool:

java -jar yuicompressor-ext-2.4.2.1.jar -x "debug" combinedapi.js > /build/myapi-release.js

The “-x” option is a shorthand for “–exclude-namespace”. This removes the global namespace named “debug”. “combinedapi.js” is the file I’m compressing. And i’m redirecting standard out to a fresh new file called “/build/myapi-release.js” (or you could just use the -o option). NOTE: This command line syntax might differ on windows.

Download source and packaged binary (bytecode)

The extended version of the YUI compressor is licensed under the Mozilla Public License (MPL)

If you have any questions/issues/comments about the extended YUI compressor add a comment to this post.

2 thoughts on “YUI JS Compressor Tool Extended

Leave a comment